<template>
    <div id="flappy_bird" tabindex="0" @keydown="handleStart">
        <h1 v-if="!isStart" class="title flex-center">任意键开始游戏
        </h1>
        <img  :style="{ '--bird-size': bird.birdSize, '--bird-top': bird.birdTop }" :src="birdImg" class="bird"/>
        <!-- <div :style="{ '--bird-size': bird.birdSize, '--bird-top': bird.birdTop }" class="bird"></div> -->

        <div v-for="(item, index) in pipes" :key="index" class="pipe"
            :style="{ '--hole-top': item.holeTop, '--hole-height': item.holeHeight, '--pipe-left': item.pipeLeft, '--pipe-width': item.pipeWidth }">
            <div class="segment top"></div>
            <div class="segment bottom"></div>
        </div>
        <RankList />
    </div>
</template>
  
<script setup lang="ts">
import { ElMessageBox } from 'element-plus'
import { setScore } from "@/api/modules/game";
import birdImg from "@/assets/img/bird.png"
const route = useRoute()
const bird = reactive({ birdSize: 60, birdTop: -60 })
const BIRD_SPEED = .3
const JUMP_DURATION = 100 //跳跃时长
const HOLE_HEIGHT = 120
const isStart = ref(false)
const isFinish = ref(false)
const passPipesCount = ref(0)
let lastTime: number;
let timeSinceLastJump = Number.POSITIVE_INFINITY; //距离上次跳跃的间隔时间

const PIPE_SPEED = 0.25
const PIPE_INTERVAL = 3000 //管道之间的间隔时间
const pipes = ref<{ holeTop: number, holeHeight: number, pipeLeft: number, pipeWidth: number }[]>([])
let timeSinceLastPipe = PIPE_INTERVAL; //距离上次创建管道的间隔时间

function updateLoop(time: number) {
    if (!lastTime) {
        lastTime = time;
    } else {
        const delta = time - lastTime;
        updateBird(delta);
        updatePipe(delta);

        if (checkLose()) return handleLose()
        lastTime = time;
    }
    requestAnimationFrame(updateLoop)
}
function handleStart(e: KeyboardEvent) {
    if (isFinish.value) return

    if (isStart.value) {
        e.code === "Space" && handleJump(e)
    } else {
        pipes.value = []
        isStart.value = true
        timeSinceLastPipe = 0;
        lastTime = 0;
        passPipesCount.value = 0;
        setupBird()
        requestAnimationFrame(updateLoop)
    }
}
function handleLose() {
    isFinish.value = true
    isStart.value = false
    setScore({ game_id: route.query.id as string, label: "" + passPipesCount.value, score: passPipesCount.value })
    ElMessageBox.confirm(`您的得分为${passPipesCount.value}，是否重新开始？`, { autofocus: false, closeOnClickModal: false, showCancelButton: false },).then(() => {
        isFinish.value = false
    })
}

function checkLose() {
    return bird.birdTop < 0 || ((bird.birdTop + bird.birdSize) > window.innerHeight) || isCollision()
}

function handleJump(e: KeyboardEvent) {
    timeSinceLastJump = 0;
}
function setupBird() {
    bird.birdTop = window.innerHeight / 2;
}
function updateBird(delta: number) {
    
    if (timeSinceLastJump < JUMP_DURATION) {
        bird.birdTop -= BIRD_SPEED * delta /2
    } else {
        bird.birdTop += BIRD_SPEED * delta
    }
    timeSinceLastJump = timeSinceLastJump + delta/2
}

function randomNumBetween(min: number, max: number) {
    return Math.floor(Math.random() * (max - min + 1) + min)
}

function createPipe() {
    pipes.value.push({ holeTop: randomNumBetween(HOLE_HEIGHT * 1.5, window.innerHeight - HOLE_HEIGHT * 0.5), holeHeight: randomNumBetween(120, 300), pipeLeft: window.innerWidth, pipeWidth: randomNumBetween(80, 200) })
}

function updatePipe(delta: number) {
    timeSinceLastPipe += delta
    if (timeSinceLastPipe > PIPE_INTERVAL) {
        createPipe()
        timeSinceLastPipe -= PIPE_INTERVAL
    }

    for (let i = 0; i < pipes.value.length; i++) {
        const pipe = pipes.value[i];
        if (pipe.pipeLeft + pipe.pipeWidth < 0) {
            pipes.value.splice(i, 1);
            passPipesCount.value++;
            i--;
            continue
        }
        pipe.pipeLeft -= PIPE_SPEED * delta;
    }

}

interface Rect {
    left: number;
    top: number;
    bottom: number;
    right: number;
}
function isCollision() {
    const birdRect: Rect = { left: bird.birdSize, top: bird.birdTop, bottom: bird.birdTop + bird.birdSize, right: 2 * bird.birdSize };

    return pipes.value.some(pipe => {
        const PipeTopRect: Rect = { left: pipe.pipeLeft, top: 0, bottom: window.innerHeight - pipe.holeTop, right: pipe.pipeLeft + pipe.pipeWidth }
        const PipeBottomRect: Rect = { left: pipe.pipeLeft, bottom: window.innerHeight, top: window.innerHeight - pipe.holeTop + pipe.holeHeight, right: pipe.pipeLeft + pipe.pipeWidth }
        return isCollect(birdRect, PipeTopRect) || isCollect(birdRect, PipeBottomRect)

    })
}
function isCollect(rect1: Rect, rect2: Rect) {
    return rect1.left < rect2.right && rect1.right > rect2.left && rect1.top < rect2.bottom && rect1.bottom > rect2.top
}


</script>
  
<style lang="scss"></style>
<style scoped lang="scss">
@import "./index.scss";
</style>
  